home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / ParseRoutines.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  31KB  |  2,053 lines

  1. /*
  2. **    $Id: ParseRoutines.c,v 1.5 92/05/09 15:53:08 olsen Sta Locker: olsen $
  3. **    $Revision: 1.5 $
  4. **    $Date: 92/05/09 15:53:08 $
  5. **
  6. **    Low-level console routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* Flag indicating whether the cursor has already been
  15.      * erased or not.
  16.      */
  17.  
  18. STATIC BYTE CursorEnabled = FALSE;
  19.  
  20.     /* Global string buffer and backup style. */
  21.  
  22. STATIC UBYTE GlobalBuffer[40],StyleType = FS_NORMAL;
  23.  
  24.     /* Cursor backup data. */
  25.  
  26. STATIC struct CursorData CursorBackup;
  27.  
  28.     /* ClipBlitCursor(UBYTE DoClip,UBYTE DoMove):
  29.      *
  30.      *    Change the appearance of the cursor.
  31.      */
  32.  
  33. VOID __regargs
  34. ClipBlitCursor(UBYTE DoClip,UBYTE DoMove)
  35. {
  36.     if(DoClip || DoMove)
  37.     {
  38.         STATIC WORD LastCursorX = -1,LastCursorY = -1;
  39.         STATIC LONG DestX,DestY,XSize,X,Y,Column;
  40.  
  41.         if(CursorY != LastCursorY || CursorX != LastCursorX)
  42.         {
  43.             if(CursorY != LastCursorY)
  44.             {
  45.                 if(CursorY > LastLine)
  46.                     Y = LastLine;
  47.                 else
  48.                 {
  49.                     if(CursorY < 0)
  50.                         Y = 0;
  51.                     else
  52.                         Y = CursorY;
  53.                 }
  54.  
  55.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  56.                     Column = LastColumn;
  57.                 else
  58.                     Column = ((LastColumn + 1) / 2) - 1;
  59.  
  60.                 DestY = Y * 8;
  61.  
  62.                 LastCursorY = CursorY;
  63.             }
  64.  
  65.             LastCursorX = CursorX;
  66.  
  67.             if(CursorX > Column)
  68.                 X = Column;
  69.             else
  70.             {
  71.                 if(CursorX < 0)
  72.                     X = 0;
  73.                 else
  74.                     X = CursorX;
  75.             }
  76.  
  77.             if(Config . FontScale == SCALE_NORMAL)
  78.             {
  79.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  80.                 {
  81.                     DestX = X * 8;
  82.                     XSize = 8;
  83.                 }
  84.                 else
  85.                 {
  86.                     DestX = X * 16;
  87.                     XSize = 16;
  88.  
  89.                     if(X > ((LastColumn + 1) / 2) - 1)
  90.                         X = ((LastColumn + 1) / 2) - 1;
  91.                 }
  92.             }
  93.             else
  94.             {
  95.                 if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  96.                 {
  97.                     DestX = X * 4;
  98.                     XSize = 4;
  99.                 }
  100.                 else
  101.                 {
  102.                     DestX = X * 8;
  103.                     XSize = 8;
  104.  
  105.                     if(X > ((LastColumn + 1) / 2) - 1)
  106.                         X = ((LastColumn + 1) / 2) - 1;
  107.                 }
  108.             }
  109.         }
  110.  
  111.         if(DoMove)
  112.             Move(RPort,DestX,DestY + 6);
  113.  
  114.         if(DoClip)
  115.         {
  116.             BYTE Depth = RPort -> BitMap -> Depth;
  117.  
  118.             if(Depth > 1 && !(Config . DisableBlinking & TERMINAL_FASTER))
  119.             {
  120.                 STATIC    UBYTE    DepthMasks[5] = { 0,1,3,7,15 };
  121.                     UBYTE    Mask = RPort -> Mask;
  122.  
  123.                 SetWrMsk(RPort,DepthMasks[Depth]);
  124.  
  125.                 ClipBlit(RPort,0,0,RPort,DestX,DestY,XSize,8,0x50);
  126.  
  127.                 SetWrMsk(RPort,Mask);
  128.             }
  129.             else
  130.                 ClipBlit(RPort,0,0,RPort,DestX,DestY,XSize,8,0x50);
  131.         }
  132.     }
  133. }
  134.  
  135.     /* ClearCursor():
  136.      *
  137.      *    Clear the cursor image.
  138.      */
  139.  
  140. VOID
  141. ClearCursor()
  142. {
  143.     if(CursorEnabled)
  144.     {
  145.         ClipBlitCursor(TRUE,FALSE);
  146.  
  147.         CursorEnabled = FALSE;
  148.     }
  149. }
  150.  
  151.     /* DrawCursor():
  152.      *
  153.      *    Explicitely (re-)draw the cursor image.
  154.      */
  155.  
  156. VOID
  157. DrawCursor()
  158. {
  159.     if(!CursorEnabled)
  160.     {
  161.         ClipBlitCursor(TRUE,FALSE);
  162.  
  163.         CursorEnabled = TRUE;
  164.     }
  165. }
  166.  
  167.     /* ColourValue(UWORD Colour):
  168.      *
  169.      *    Calculate the value of a given colour (brightness).
  170.      */
  171.  
  172. STATIC WORD __regargs
  173. ColourValue(UWORD Colour)
  174. {
  175.     BYTE    Red,Green,Blue;
  176.     WORD    Sum;
  177.  
  178.     Red    =  Colour >> 8       ;
  179.     Green    = (Colour >> 4) & 0xF;
  180.     Blue    =  Colour       & 0xF;
  181.  
  182.     Sum = (Red + Green + Blue) / 3;
  183.  
  184.     return(Sum);
  185. }
  186.  
  187.     /* SetCursor():
  188.      *
  189.      *    Move the cursor to a given location.
  190.      */
  191.  
  192. VOID
  193. SetCursor()
  194. {
  195.     ClipBlitCursor(!CursorEnabled,TRUE);
  196.  
  197.     CursorEnabled = TRUE;
  198. }
  199.  
  200.     /* BackupRender():
  201.      *
  202.      *    Save current draw modes, pen and position or restore
  203.      *    the data.
  204.      */
  205.  
  206. VOID
  207. BackupRender()
  208. {
  209.     STATIC BYTE    Called = FALSE;
  210.     STATIC UBYTE    DrMd,FgPen,BgPen;
  211.     STATIC UWORD    CpX,CpY;
  212.     STATIC UBYTE    Style;
  213.  
  214.     if(!Called)
  215.     {
  216.         DrMd    = RPort -> DrawMode;
  217.         FgPen    = RPort -> FgPen;
  218.         BgPen    = RPort -> BgPen;
  219.  
  220.         CpX    = RPort -> cp_x;
  221.         CpY    = RPort -> cp_y;
  222.  
  223.         Style    = StyleType;
  224.  
  225.         Called    = TRUE;
  226.     }
  227.     else
  228.     {
  229.         if(RPort -> DrawMode != DrMd)
  230.             SetDrMd(RPort,DrMd);
  231.  
  232.         if(RPort -> FgPen != FgPen)
  233.             SetAPen(RPort,FgPen);
  234.  
  235.         if(RPort -> BgPen != BgPen)
  236.             SetBPen(RPort,BgPen);
  237.  
  238.         if(RPort -> cp_x != CpX || RPort -> cp_y != CpY)
  239.             Move(RPort,CpX,CpY);
  240.  
  241.         if(Style != StyleType)
  242.         {
  243.             SetSoftStyle(RPort,Style,0xFF);
  244.  
  245.             StyleType = Style;
  246.         }
  247.  
  248.         Called = FALSE;
  249.     }
  250. }
  251.  
  252.     /* ShiftChar(LONG Size):
  253.      *
  254.      *    Simulate character insertion at the current cursor
  255.      *    position by shifting the whole line Size times eight pixels
  256.      *    to the right.
  257.      */
  258.  
  259. VOID __regargs
  260. ShiftChar(LONG Size)
  261. {
  262.     LONG DeltaX,MinX,MinY;
  263.  
  264.     MinY = CursorY * 8;
  265.  
  266.     if(Config . FontScale == SCALE_NORMAL)
  267.     {
  268.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  269.         {
  270.             DeltaX    = Size * 8;
  271.             MinX    = CursorX * 8;
  272.         }
  273.         else
  274.         {
  275.             DeltaX    = Size * 4;
  276.             MinX    = CursorX * 4;
  277.         }
  278.     }
  279.     else
  280.     {
  281.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  282.         {
  283.             DeltaX    = Size * 4;
  284.             MinX    = CursorX * 4;
  285.         }
  286.         else
  287.         {
  288.             DeltaX    = Size * 8;
  289.             MinX    = CursorX * 8;
  290.         }
  291.     }
  292.  
  293.     if(MinX < Window -> Width)
  294.     {
  295.         BackupRender();
  296.  
  297.         SetBPen(RPort,0);
  298.  
  299.         ScrollLineRaster(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + 7);
  300.  
  301.         BackupRender();
  302.     }
  303. }
  304.  
  305.     /* ScrollRegion(WORD Direction):
  306.      *
  307.      *    Scroll the current scroll region up or down.
  308.      */
  309.  
  310. STATIC VOID __regargs
  311. ScrollRegion(WORD Direction)
  312. {
  313.     WORD RegionTop,RegionBottom,RegionLines;
  314.     LONG Dir,MinY,MaxY;
  315.  
  316.     if(Direction < 0)
  317.         Dir = -Direction;
  318.     else
  319.         Dir = Direction;
  320.  
  321.     if(RegionSet)
  322.     {
  323.         MinY         = Top * 8;
  324.         MaxY        = (Bottom + 1) * 8 - 1;
  325.  
  326.         RegionTop    = Top;
  327.         RegionBottom    = Bottom + 1;
  328.         RegionLines    = Bottom - Top + 1;
  329.     }
  330.     else
  331.     {
  332.         MinY        = 0;
  333.         MaxY         = (LastLine + 1) * 8 - 1;
  334.  
  335.         RegionTop    = 0;
  336.         RegionBottom    = LastLine + 1;
  337.         RegionLines    = LastLine + 1;
  338.     }
  339.  
  340.     BackupRender();
  341.  
  342.     SetBPen(RPort,0);
  343.  
  344.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  345.  
  346.     if(Dir > RegionLines)
  347.     {
  348.         /* All that is needed is to delete the lines
  349.          * note: not too brilliant for smooth scroll
  350.          */
  351.  
  352.         ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  353.     }
  354.     else
  355.     {
  356.         if(Config . JumpScroll)
  357.             ScrollLineRaster(RPort,0,Direction * 8,0,MinY,LastPixel,MaxY);
  358.         else
  359.         {
  360.             WORD Lines = Dir * 4;
  361.  
  362.             if(Direction < 0)
  363.             {
  364.                 while(Lines--)
  365.                 {
  366.                     WaitTOF();
  367.  
  368.                     ScrollLineRaster(RPort,0,-2,0,MinY,LastPixel,MaxY);
  369.                 }
  370.             }
  371.             else
  372.             {
  373.                 while(Lines--)
  374.                 {
  375.                     WaitTOF();
  376.  
  377.                     ScrollLineRaster(RPort,0,2,0,MinY,LastPixel,MaxY);
  378.                 }
  379.             }
  380.         }
  381.     }
  382.  
  383.     BackupRender();
  384. }
  385.  
  386.     /* LastChar(UBYTE *Buffer):
  387.      *
  388.      *    Return the last character in a string.
  389.      */
  390.  
  391. STATIC UBYTE __regargs
  392. LastChar(UBYTE *Buffer)
  393. {
  394.     WORD Offset = 0;
  395.  
  396.     while(Buffer[Offset])
  397.         Offset++;
  398.  
  399.     return(Buffer[Offset - 1]);
  400. }
  401.  
  402.     /* ReadValue(UBYTE *Buffer,BYTE *Value):
  403.      *
  404.      *    Parse a buffer for numbers and return a pointer
  405.      *    to the next buffer element to contain additional
  406.      *    information.
  407.      */
  408.  
  409. STATIC UBYTE * __regargs
  410. ReadValue(UBYTE *Buffer,WORD *Value)
  411. {
  412.     while((*Buffer < '0' || *Buffer > '9') && (*Buffer != ';') && *Buffer)
  413.         Buffer++;
  414.  
  415.     if(*Buffer)
  416.     {
  417.         *Value = 0;
  418.  
  419.         while(*Buffer >= '0' && *Buffer <= '9')
  420.             *Value = (*Value * 10) + (*Buffer++ - '0');
  421.     }
  422.     else
  423.         *Value = -1;
  424.  
  425.     if(*Buffer == ';' || *Buffer == ' ')
  426.         return(&Buffer[1]);
  427.     else
  428.         return(NULL);
  429. }
  430.  
  431.     /* Ignore():
  432.      *
  433.      *    Do nothing, return immediately.
  434.      */
  435.  
  436. UBYTE *
  437. Ignore()
  438. {
  439.     return(NULL);
  440. }
  441.  
  442.     /* ScrollDown(UBYTE *Buffer):
  443.      *
  444.      *    Scroll the current region down.
  445.      */
  446.  
  447. UBYTE * __regargs
  448. ScrollDown(UBYTE *Buffer)
  449. {
  450.     WORD Value;
  451.  
  452.     ReadValue(Buffer,&Value);
  453.  
  454.     if(Value < 1)
  455.         Value = 1;
  456.  
  457.     ClearCursor();
  458.  
  459.     ScrollRegion(-Value);
  460.  
  461.     DrawCursor();
  462.  
  463.     return(NULL);
  464. }
  465.  
  466.     /* ScrollUp(UBYTE *Buffer):
  467.      *
  468.      *    Scroll the current region up.
  469.      */
  470.  
  471. UBYTE * __regargs
  472. ScrollUp(UBYTE *Buffer)
  473. {
  474.     WORD Value;
  475.  
  476.     ReadValue(Buffer,&Value);
  477.  
  478.     if(Value < 1)
  479.         Value = 1;
  480.  
  481.     ClearCursor();
  482.  
  483.     ScrollRegion(Value);
  484.  
  485.     DrawCursor();
  486.  
  487.     return(NULL);
  488. }
  489.  
  490.     /* CursorScrollDown():
  491.      *
  492.      *    Move cursor down and scroll region if necessary.
  493.      */
  494.  
  495. UBYTE *
  496. CursorScrollDown()
  497. {
  498.     ClearCursor();
  499.  
  500.     DownLine();
  501.  
  502.     SetCursor();
  503.  
  504.     return(NULL);
  505. }
  506.  
  507. VOID
  508. DownLine()
  509. {
  510.     UBYTE InRegion = TRUE;
  511.     WORD  Hit      = LastLine;
  512.  
  513.     if(RegionSet)
  514.     {
  515.         if(CursorY <= Bottom)
  516.             Hit = Bottom;
  517.         else
  518.             InRegion = FALSE;
  519.     }
  520.  
  521.     if(CursorY == Hit)
  522.     {
  523.         if(InRegion)
  524.             ScrollRegion(1);
  525.     }
  526.     else
  527.     {
  528.         CursorY++;
  529.  
  530.         if(CursorY > LastLine)
  531.             CursorY = LastLine;
  532.     }
  533. }
  534.  
  535.     /* CursorScrollUp():
  536.      *
  537.      *    Move cursor up and scroll region if necessary.
  538.      */
  539.  
  540. UBYTE *
  541. CursorScrollUp()
  542. {
  543.     BYTE InRegion    = TRUE;
  544.     WORD Hit    = 0;
  545.  
  546.     ClearCursor();
  547.  
  548.     if(RegionSet)
  549.     {
  550.         if(CursorY >= Top)
  551.             Hit = Top;
  552.         else
  553.             InRegion = FALSE;
  554.     }
  555.  
  556.     if(CursorY == Hit)
  557.     {
  558.         if(InRegion)
  559.             ScrollRegion(-1);
  560.     }
  561.     else
  562.     {
  563.         if(--CursorY < 0)
  564.             CursorY = 0;
  565.     }
  566.  
  567.     SetCursor();
  568.  
  569.     return(NULL);
  570. }
  571.  
  572.     /* NextLine():
  573.      *
  574.      *    Do something like CR+LF.
  575.      */
  576.  
  577. UBYTE *
  578. NextLine()
  579. {
  580.     ClearCursor();
  581.  
  582.     CursorX = 0;
  583.  
  584.     DownLine();
  585.  
  586.     SetCursor();
  587.  
  588.     return(NULL);
  589. }
  590.  
  591.     /* SaveCursor():
  592.      *
  593.      *    Save cursor position and rendering attributes.
  594.      */
  595.  
  596. UBYTE *
  597. SaveCursor()
  598. {
  599.     CursorBackup . Charset        = Charset;
  600.     CursorBackup . Attributes    = Attributes;
  601.     CursorBackup . CursorX        = CursorX;
  602.     CursorBackup . CursorY        = CursorY;
  603.     CursorBackup . Style        = StyleType;
  604.     CursorBackup . FgPen        = RPort -> FgPen;
  605.     CursorBackup . BgPen        = RPort -> BgPen;
  606.     CursorBackup . CurrentFont    = CurrentFont;
  607.  
  608.     return(NULL);
  609. }
  610.  
  611.     /* FontStuff(UBYTE *Buffer):
  612.      *
  613.      *    Set the drawing font (standard characters/line).
  614.      */
  615.  
  616. UBYTE * __regargs
  617. FontStuff(UBYTE *Buffer)
  618. {
  619.     BYTE Changed = FALSE;
  620.  
  621.     if(Buffer[0] == '(')
  622.     {
  623.         switch(LastChar(Buffer))
  624.         {
  625.             case 'A':
  626.             case 'B':    if(CharMode[0] != TABLE_ASCII && !Charset)
  627.                         Changed = TRUE;
  628.  
  629.                     CharMode[0] = TABLE_ASCII;
  630.  
  631.                     break;
  632.  
  633.             case '0':    if(CharMode[0] != TABLE_GFX && !Charset)
  634.                         Changed = TRUE;
  635.  
  636.                     CharMode[0] = TABLE_GFX;
  637.  
  638.                     break;
  639.         }
  640.     }
  641.  
  642.     if(Buffer[0] == ')')
  643.     {
  644.         switch(LastChar(Buffer))
  645.         {
  646.             case 'A':
  647.             case 'B':    if(CharMode[1] != TABLE_ASCII && Charset == 1)
  648.                         Changed = TRUE;
  649.  
  650.                     CharMode[1] = TABLE_ASCII;
  651.  
  652.                     break;
  653.  
  654.             case '0':    if(CharMode[1] != TABLE_GFX && Charset == 1)
  655.                         Changed = TRUE;
  656.  
  657.                     CharMode[1] = TABLE_GFX;
  658.  
  659.                     break;
  660.         }
  661.     }
  662.  
  663.     if(Changed)
  664.     {
  665.         BackupRender();
  666.  
  667.         if(Charset)
  668.             DoShiftIn();
  669.         else
  670.             DoShiftOut();
  671.  
  672.         BackupRender();
  673.     }
  674.  
  675.     return(NULL);
  676. }
  677.  
  678.     /* LoadCursor():
  679.      *
  680.      *    Load cursor position and rendering attributes.
  681.      */
  682.  
  683. UBYTE *
  684. LoadCursor()
  685. {
  686.     ClearCursor();
  687.  
  688.     Charset        = CursorBackup . Charset;
  689.  
  690.     CharMode[0]    = CursorBackup . CharMode[0];
  691.     CharMode[1]    = CursorBackup . CharMode[1];
  692.  
  693.     if(CurrentFont != CursorBackup . CurrentFont)
  694.     {
  695.         CurrentFont = CursorBackup . CurrentFont;
  696.  
  697.         SetFont(RPort,CurrentFont);
  698.     }
  699.  
  700.     if(StyleType != CursorBackup . Style)
  701.     {
  702.         SetSoftStyle(RPort,CursorBackup . Style,0xFF);
  703.  
  704.         StyleType = CursorBackup . Style;
  705.     }
  706.  
  707.     if(RPort -> FgPen != CursorBackup . FgPen)
  708.         SetAPen(RPort,CursorBackup . FgPen);
  709.  
  710.     if(RPort -> BgPen != CursorBackup . BgPen)
  711.         SetBPen(RPort,CursorBackup . BgPen);
  712.  
  713.     Attributes    = CursorBackup . Attributes;
  714.     CursorX        = CursorBackup . CursorX;
  715.     CursorY        = CursorBackup . CursorY;
  716.  
  717.     SetCursor();
  718.  
  719.     return(NULL);
  720. }
  721.  
  722. UBYTE * __regargs
  723. ScaleFont(UBYTE *Buffer)
  724. {
  725.     WORD NewScale,Scale;
  726.  
  727.     Scale = RasterAttr[CursorY];
  728.  
  729.     ClearCursor();
  730.  
  731.     NewScale = Scale;
  732.  
  733.     switch(LastChar(Buffer))
  734.     {
  735.         case '3':
  736.  
  737.             NewScale = SCALE_ATTR_TOP2X;
  738.  
  739.             break;
  740.  
  741.         case '4':
  742.  
  743.             NewScale = SCALE_ATTR_BOT2X;
  744.  
  745.             break;
  746.  
  747.         case '5':
  748.  
  749.             NewScale = SCALE_NORMAL;
  750.  
  751.             break;
  752.  
  753.         case '6':
  754.  
  755.             NewScale = SCALE_ATTR_2X;
  756.  
  757.             break;
  758.     }
  759.  
  760.     if(Scale != NewScale)
  761.     {
  762.         UBYTE    *RasterPtr    = &Raster[CursorY * RasterWidth];
  763.         WORD     RightMargin    = LastColumn + 1,
  764.              CursorXSave    = CursorX;
  765.  
  766.         if(NewScale != SCALE_ATTR_NORMAL)
  767.             RightMargin /= 2;
  768.  
  769.         RasterAttr[CursorY] = NewScale;
  770.  
  771.         if(((Config . FontScale == SCALE_NORMAL) && (NewScale == SCALE_ATTR_NORMAL)) || ((Config . FontScale == SCALE_HALF) && (NewScale == SCALE_ATTR_2X)))
  772.         {
  773.             Move(RPort,0,CursorY * 8 + 6);
  774.             Text(RPort,RasterPtr,RightMargin);
  775.         }
  776.         else
  777.         {
  778.             CursorX = 0;
  779.  
  780.             PrintScaled(RasterPtr,RightMargin,NewScale);
  781.         }
  782.  
  783.         if(CursorXSave >= RightMargin)
  784.             CursorX = RightMargin - 1;
  785.         else
  786.             CursorX = CursorXSave;
  787.     }
  788.  
  789.     SetCursor();
  790.  
  791.     return(NULL);
  792. }
  793.  
  794. UBYTE *
  795. AlignmentTest()
  796. {
  797.     STRPTR Buffer;
  798.  
  799.     if(Buffer = AllocVec(LastColumn + 1,MEMF_ANY))
  800.     {
  801.         WORD i;
  802.  
  803.         memset(Buffer,'E',LastColumn + 1);
  804.  
  805.         EraseScreen("2");
  806.  
  807.         ClearCursor();
  808.  
  809.         if(Config . FontScale == SCALE_HALF)
  810.         {
  811.             for(i = 0 ; i <= LastLine ; i++)
  812.             {
  813.                 CursorX = 0;
  814.                 CursorY = i;
  815.  
  816.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  817.  
  818.                 RasterPutString(Buffer,LastColumn + 1);
  819.                 ScrollLinePutString(LastColumn + 1);
  820.  
  821.                 Move(RPort,0,(i * 8) + 6);
  822.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  823.             }
  824.         }
  825.         else
  826.         {
  827.             for(i = 0 ; i <= LastLine ; i++)
  828.             {
  829.                 CursorX = 0;
  830.                 CursorY = i;
  831.  
  832.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  833.  
  834.                 RasterPutString(Buffer,LastColumn + 1);
  835.                 ScrollLinePutString(LastColumn + 1);
  836.  
  837.                 Move(RPort,0,(i * 8) + 6);
  838.                 Text(RPort,Buffer,LastColumn + 1);
  839.             }
  840.         }
  841.  
  842.         CursorX = CursorY = 0;
  843.  
  844.         SetCursor();
  845.  
  846.         FreeVec(Buffer);
  847.     }
  848.  
  849.     return(NULL);
  850. }
  851.  
  852.     /* SetTab():
  853.      *
  854.      *    Set a tabulator stop at the current position.
  855.      */
  856.  
  857. UBYTE *
  858. SetTab()
  859. {
  860.     if(CursorX < 1024)
  861.         TabStops[CursorX] = TRUE;
  862.  
  863.     return(NULL);
  864. }
  865.  
  866.     /* RequestTerminal(UBYTE *Buffer):
  867.      *
  868.      *    Return the current terminal position.
  869.      */
  870.  
  871. UBYTE * __regargs
  872. RequestTerminal(UBYTE *Buffer)
  873. {
  874.     switch(Buffer[0])
  875.     {
  876.                 /* Make ourselves known as a VT200
  877.                  * terminal.
  878.                  */
  879.  
  880.         case '[':    if(Buffer[1] != '>')
  881.                     return("\033[?62;1;2;6;7;8;9c");
  882.                 else
  883.                     return("\033[>1;10;0c");
  884.  
  885.                 /* This is an old status request type,
  886.                  * we will return the standard `I am a
  887.                  * VT101' sequence.
  888.                  */
  889.  
  890.         case 'Z':    return("\033[?1;0c");
  891.  
  892.         default:    return(NULL);
  893.     }
  894. }
  895.  
  896.     /* Reset():
  897.      *
  898.      *    Reset terminal to initial state.
  899.      */
  900.  
  901. UBYTE *
  902. Reset()
  903. {
  904.     WORD i;
  905.  
  906.     ClearCursor();
  907.  
  908.     memset(&TabStops[0],FALSE,1024);
  909.  
  910.     for(i = 8 ; i < 1024 ; i += 8)
  911.         TabStops[i] = TRUE;
  912.  
  913.     CharMode[0] = TABLE_ASCII;
  914.     CharMode[1] = TABLE_GFX;
  915.  
  916.     Charset = 0;
  917.  
  918.     SetRast(RPort,0);
  919.  
  920.     ScrollLineEraseScreen(2);
  921.  
  922.     RasterEraseScreen(2);
  923.  
  924.     switch(Config . ColourMode)
  925.     {
  926.         case COLOUR_EIGHT:    FgPen = 7;
  927.                     break;
  928.  
  929.         case COLOUR_SIXTEEN:    FgPen = 15;
  930.                     break;
  931.  
  932.         case COLOUR_AMIGA:
  933.         default:        FgPen = 1;
  934.                     break;
  935.     }
  936.  
  937.     BgPen = 0;
  938.  
  939.     if(RPort -> FgPen != FgPen)
  940.         SetAPen(RPort,FgPen);
  941.  
  942.     if(RPort -> BgPen != BgPen)
  943.         SetBPen(RPort,BgPen);
  944.  
  945.     if(StyleType != FS_NORMAL)
  946.     {
  947.         SetSoftStyle(RPort,FS_NORMAL,0xFF);
  948.  
  949.         StyleType = FS_NORMAL;
  950.     }
  951.  
  952.     if(Config . Font == FONT_IBM && IBM)
  953.         CurrentFont = IBM;
  954.     else
  955.         CurrentFont = Topaz;
  956.  
  957.     SetFont(RPort,CurrentFont);
  958.  
  959.     if(Config . EightyColumns)
  960.     {
  961.         LastColumn = 79;
  962.  
  963.         LastPixel = 80 * 8 - 1;
  964.     }
  965.     else
  966.     {
  967.         LastColumn = ((Window -> Width & ~7) / 8) - 1;
  968.  
  969.         LastPixel = (Window -> Width & ~7) - 1;
  970.     }
  971.  
  972.     UseRegion        = FALSE;
  973.     RegionSet        = FALSE;
  974.  
  975.     Config . AutoWrap    = TRUE;
  976.     Config . NewLine    = FALSE;
  977.     Config . InsertChar    = FALSE;
  978.     Config . CursorApp    = FALSE;
  979.     Config . NumApp        = FALSE;
  980.     Config . FontScale    = SCALE_NORMAL;
  981.     Config . JumpScroll    = TRUE;
  982.  
  983.     Attributes    = 0;
  984.     Top        = 0;
  985.     Bottom        = LastLine;
  986.     CursorX        = 0;
  987.     CursorY        = 0;
  988.  
  989.     CursorBackup . Charset        = Charset;
  990.     CursorBackup . Attributes    = Attributes;
  991.     CursorBackup . CursorX        = CursorX;
  992.     CursorBackup . CursorY        = CursorY;
  993.     CursorBackup . Style        = StyleType;
  994.     CursorBackup . FgPen        = FgPen;
  995.     CursorBackup . BgPen        = BgPen;
  996.     CursorBackup . CurrentFont    = CurrentFont;
  997.  
  998.     SetCursor();
  999.  
  1000.     return(NULL);
  1001. }
  1002.  
  1003.     /* PrinterController(UBYTE *Buffer):
  1004.      *
  1005.      *    Controls various screen dump and capture functions.
  1006.      */
  1007.  
  1008. UBYTE * __regargs
  1009. PrinterController(UBYTE *Buffer)
  1010. {
  1011.     switch(Buffer[1])
  1012.     {
  1013.         case 'i':
  1014.         case '0':    if(RegionSet)
  1015.                     PrintRegion(Top,Bottom + 1);
  1016.                 else
  1017.                     PrintRegion(0,LastLine + 1);
  1018.  
  1019.                 break;
  1020.  
  1021.         case '5':    OpenPrinterCapture(TRUE);
  1022.                 break;
  1023.  
  1024.         case '4':    ClosePrinterCapture(FALSE);
  1025.                 break;
  1026.     }
  1027.  
  1028.     return(NULL);
  1029. }
  1030.  
  1031.     /* RequestInformation(UBYTE *Buffer):
  1032.      *
  1033.      *    Request miscellaneous information (state & cursor position).
  1034.      */
  1035.  
  1036. UBYTE * __regargs
  1037. RequestInformation(UBYTE *Buffer)
  1038. {
  1039.     WORD Value;
  1040.  
  1041.     ReadValue(Buffer,&Value);
  1042.  
  1043.     switch(Value)
  1044.     {
  1045.                 /* Terminal status report, return code
  1046.                  * for `no malfunction'.
  1047.                  */
  1048.  
  1049.         case 5:        return("\033[0n");
  1050.  
  1051.                 /* The origin is placed at 0/0 and the first
  1052.                  * cursor position is 1/1. We'll have to add
  1053.                  * 1 to our internal positions since our
  1054.                  * universe has been shifted one field to the
  1055.                  * left top corner.
  1056.                  */
  1057.  
  1058.         case 6:        SPrintf(GlobalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1059.                 return(GlobalBuffer);
  1060.  
  1061.                 /* A VT200 command: request printer status.
  1062.                  * We will return `the printer is ready'.
  1063.                  */
  1064.  
  1065.         case 15:    return("\033[?10n");
  1066.  
  1067.                 /* VT200 command: request user defined
  1068.                  * key status. We will return `user
  1069.                  * defined keys are locked'.
  1070.                  */
  1071.  
  1072.         case 25:    return("\033[?21n");
  1073.  
  1074.                 /* Another VT200 command: request
  1075.                  * keyboard language. We will return
  1076.                  * `keyboard language unknown' - does
  1077.                  * anybody know when locale.library will
  1078.                  * be released?
  1079.                  */
  1080.  
  1081.         case 26:    return("\033[?27;0n");
  1082.  
  1083.         default:    return(NULL);
  1084.     }
  1085. }
  1086.  
  1087.     /* SetSomething(UBYTE *Buffer):
  1088.      *
  1089.      *    Set a terminal option.
  1090.      */
  1091.  
  1092. UBYTE * __regargs
  1093. SetSomething(UBYTE *Buffer)
  1094. {
  1095.     switch(Buffer[1])
  1096.     {
  1097.         case '?':
  1098.  
  1099.             switch(Buffer[2])
  1100.             {
  1101.                     /* Set cursor keys applications mode. */
  1102.  
  1103.                 case '1':    if(Buffer[3] == 'h')
  1104.                             Config . CursorApp = TRUE;
  1105.                         else
  1106.                             Config . CursorApp = FALSE;
  1107.  
  1108.                         return(NULL);
  1109.  
  1110.                     /* Set line length (132 or 80). */
  1111.  
  1112.                 case '3':    ClearCursor();
  1113.  
  1114.                         if(Buffer[3] == 'h')
  1115.                         {
  1116.                             if(Config . FontScale != SCALE_HALF)
  1117.                             {
  1118.                                 Config . FontScale = SCALE_HALF;
  1119.  
  1120.                                 if(Config . EightyColumns)
  1121.                                 {
  1122.                                     LastColumn = 131;
  1123.  
  1124.                                     LastPixel = 80 * 8 - 1;
  1125.                                 }
  1126.                                 else
  1127.                                 {
  1128.                                     LastColumn = ((Window -> Width & ~7) / 4) - 1;
  1129.  
  1130.                                     LastPixel = (Window -> Width & ~7) - 1;
  1131.                                 }
  1132.                             }
  1133.                         }
  1134.                         else
  1135.                         {
  1136.                             if(Config . FontScale != SCALE_NORMAL)
  1137.                             {
  1138.                                 Config . FontScale = SCALE_NORMAL;
  1139.  
  1140.                                 if(Config . EightyColumns)
  1141.                                 {
  1142.                                     LastColumn = 79;
  1143.  
  1144.                                     LastPixel = 80 * 8 - 1;
  1145.                                 }
  1146.                                 else
  1147.                                 {
  1148.                                     LastColumn = ((Window -> Width & ~7) / 8) - 1;
  1149.  
  1150.                                     LastPixel = (Window -> Width & ~7) - 1;
  1151.                                 }
  1152.                             }
  1153.                         }
  1154.  
  1155.                         CursorX = CursorY = 0;
  1156.  
  1157.                         SetCursor();
  1158.  
  1159.                         EraseScreen("2");
  1160.  
  1161.                         return(NULL);
  1162.  
  1163.                     /* Set scroll mode (jump or smooth). */
  1164.  
  1165.                 case '4':    if(Buffer[3] == 'h')
  1166.                             Config . JumpScroll = FALSE;
  1167.                         else
  1168.                             Config . JumpScroll = TRUE;
  1169.  
  1170.                         break;
  1171.  
  1172.                     /* Turn region on or off. */
  1173.  
  1174.                 case '6':    if(Buffer[3] == 'h')
  1175.                             UseRegion = TRUE;
  1176.                         else
  1177.                             UseRegion = FALSE;
  1178.  
  1179.                         ResetCursor();
  1180.  
  1181.                         return(NULL);
  1182.  
  1183.                     /* Turn character wrapping on or off. */
  1184.  
  1185.                 case '7':    if(Buffer[3] == 'h')
  1186.                             Config . AutoWrap = TRUE;
  1187.                         else
  1188.                             Config . AutoWrap = FALSE;
  1189.  
  1190.                         return(NULL);
  1191.  
  1192.                     /* Set interlaced mode. */
  1193.  
  1194.                 case '9':    if(Buffer[3] == 'h')
  1195.                         {
  1196.                             if(!(Config . DisplayMode & LACE))
  1197.                             {
  1198.                                 CopyMem(&Config,&PrivateConfig,sizeof(struct Configuration));
  1199.  
  1200.                                 Config . DisplayMode |= LACE;
  1201.  
  1202.                                 ResetDisplay = TRUE;
  1203.                             }
  1204.                         }
  1205.                         else
  1206.                         {
  1207.                             if(Config . DisplayMode & LACE)
  1208.                             {
  1209.                                 CopyMem(&Config,&PrivateConfig,sizeof(struct Configuration));
  1210.  
  1211.                                 Config . DisplayMode &= ~LACE;
  1212.  
  1213.                                 ResetDisplay = TRUE;
  1214.                             }
  1215.                         }
  1216.  
  1217.                         return(NULL);
  1218.  
  1219.                 default:    return(NULL);
  1220.             }
  1221.  
  1222.             break;
  1223.  
  1224.         case '2':
  1225.  
  1226.                 /* Set newline mode. */
  1227.  
  1228.             if(Buffer[2] == '0')
  1229.             {
  1230.                 if(Buffer[3] == 'h')
  1231.                     Config . NewLine = TRUE;
  1232.                 else
  1233.                     Config . NewLine = FALSE;
  1234.             }
  1235.  
  1236.             break;
  1237.  
  1238.         case '4':
  1239.  
  1240.                 /* Set insert mode. */
  1241.  
  1242.             if(Buffer[2] == 'h')
  1243.                 Config . InsertChar = TRUE;
  1244.             else
  1245.                 Config . InsertChar = FALSE;
  1246.  
  1247.             break;
  1248.  
  1249.         case '1':
  1250.  
  1251.                 /* Print region or screen. */
  1252.  
  1253.             if(Buffer[2] == '9')
  1254.             {
  1255.                 if(Buffer[3] == 'l')
  1256.                 {
  1257.                     if(RegionSet)
  1258.                         PrintRegion(Top,Bottom + 1);
  1259.                     else
  1260.                         PrintRegion(0,LastLine + 1);
  1261.                 }
  1262.  
  1263.                 if(Buffer[3] == 'h')
  1264.                     PrintRegion(0,LastLine + 1);
  1265.             }
  1266.  
  1267.             break;
  1268.     }
  1269.  
  1270.     return(NULL);
  1271. }
  1272.  
  1273.     /* NumericAppMode(UBYTE *Buffer):
  1274.      *
  1275.      *    Set the numeric pad applications mode.
  1276.      */
  1277.  
  1278. UBYTE * __regargs
  1279. NumericAppMode(UBYTE *Buffer)
  1280. {
  1281.     if(*Buffer == '=')
  1282.         Config . NumApp = TRUE;
  1283.     else
  1284.     {
  1285.         if(*Buffer == '>')
  1286.             Config . NumApp = FALSE;
  1287.     }
  1288.  
  1289.     return(NULL);
  1290. }
  1291.  
  1292.     /* MoveCursor(UBYTE *Buffer):
  1293.      *
  1294.      *    Move the cursor in some direction and stop at
  1295.      *    top/bottom/margin if necessary.
  1296.      */
  1297.  
  1298. UBYTE * __regargs
  1299. MoveCursor(UBYTE *Buffer)
  1300. {
  1301.     WORD Value,Hit,LastCharPosition;
  1302.     BYTE InRegion = TRUE;
  1303.  
  1304.     ReadValue(Buffer,&Value);
  1305.  
  1306.     if(Value < 1)
  1307.         Value = 1;
  1308.  
  1309.     ClearCursor();
  1310.  
  1311.     switch(LastChar(Buffer))
  1312.     {
  1313.             /* Move cursor Up value lines */
  1314.  
  1315.         case 'A':
  1316.  
  1317. ScrollUp:            Hit = 0;
  1318.  
  1319.                 if(RegionSet)
  1320.                 {
  1321.                     if(CursorY >= Top)
  1322.                         Hit = Top;
  1323.                     else
  1324.                         InRegion = FALSE;
  1325.                 }
  1326.  
  1327.                 CursorY -= Value;
  1328.  
  1329.                 if(CursorY < Hit)
  1330.                 {
  1331.                     Value = CursorY - Hit;
  1332.  
  1333.                     CursorY = Hit;
  1334.  
  1335.                     if(Config . CursorWrap && InRegion)
  1336.                         ScrollRegion(Value);
  1337.                 }
  1338.  
  1339.                 break;
  1340.  
  1341.             /* Move cursor Down value lines */
  1342.  
  1343.         case 'B':
  1344.  
  1345. ScrollDown:            Hit = LastLine;
  1346.  
  1347.                 if(RegionSet)
  1348.                 {
  1349.                     if(CursorY <= Bottom)
  1350.                         Hit = Bottom;
  1351.                     else
  1352.                         InRegion = FALSE;
  1353.                 }
  1354.  
  1355.                 CursorY += Value;
  1356.  
  1357.                 if(CursorY > Hit)
  1358.                 {
  1359.                     Value = CursorY - Hit;
  1360.  
  1361.                     CursorY = Hit;
  1362.  
  1363.                     if(Config . CursorWrap && InRegion)
  1364.                         ScrollRegion(Value);
  1365.                 }
  1366.  
  1367.                 break;
  1368.  
  1369.             /* Move cursor Right value columns */
  1370.  
  1371.         case 'C':    CursorX += Value;
  1372.  
  1373.                 if(CursorX > LastColumn)
  1374.                 {
  1375.                     if(Config . CursorWrap)
  1376.                     {
  1377.                         Value     = CursorX / (LastColumn + 1);
  1378.  
  1379.                         CursorX    -= Value * (LastColumn + 1);
  1380.  
  1381.                         goto ScrollDown;
  1382.                     }
  1383.                     else
  1384.                         CursorX = LastColumn;
  1385.                 }
  1386.  
  1387.                 break;
  1388.  
  1389.             /* Move cursor Left value columns */
  1390.  
  1391.         case 'D':    CursorX -= Value;
  1392.  
  1393.                 if(CursorX < 0)
  1394.                 {
  1395.                     if(Config . CursorWrap)
  1396.                     {
  1397.                         Value     = CursorX / (LastColumn + 1);
  1398.                         CursorX    -= Value * (LastColumn + 1);
  1399.                         Value     = -Value;
  1400.  
  1401.                         goto ScrollDown;
  1402.                     }
  1403.                     else
  1404.                         CursorX = 0;
  1405.                 }
  1406.  
  1407.                 break;
  1408.  
  1409.         default:    break;
  1410.     }
  1411.  
  1412.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1413.         LastCharPosition = LastColumn;
  1414.     else
  1415.         LastCharPosition = ((LastColumn + 1) / 2) - 1;
  1416.  
  1417.     if(CursorX > LastCharPosition)
  1418.         CursorX = LastCharPosition;
  1419.  
  1420.     SetCursor();
  1421.  
  1422.     return(NULL);
  1423. }
  1424.  
  1425.     /* EraseLine(UBYTE *Buffer):
  1426.      *
  1427.      *    Erase a line on the display.
  1428.      */
  1429.  
  1430. UBYTE * __regargs
  1431. EraseLine(UBYTE *Buffer)
  1432. {
  1433.     WORD Value;
  1434.     BYTE Shift;
  1435.  
  1436.     if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  1437.         Shift = 4;
  1438.     else
  1439.     {
  1440.         if(Config . FontScale == SCALE_HALF)
  1441.             Shift = 2;
  1442.         else
  1443.             Shift = 3;
  1444.     }
  1445.  
  1446.     ReadValue(Buffer,&Value);
  1447.  
  1448.     BackupRender();
  1449.  
  1450.     SetAPen(RPort,0);
  1451.  
  1452.     ClearCursor();
  1453.  
  1454.     switch(Value)
  1455.     {
  1456.         case 1:    ScrollLineRectFill(RPort,0,CursorY * 8,((CursorX + 1) << Shift) - 1,(CursorY + 1) * 8 - 1);
  1457.             break;
  1458.  
  1459.         case 2:    ScrollLineRectFill(RPort,0,CursorY * 8,LastPixel,(CursorY + 1) * 8 - 1);
  1460.             break;
  1461.  
  1462.         default:ScrollLineRectFill(RPort,CursorX << Shift,CursorY * 8,LastPixel,(CursorY + 1) * 8 - 1);
  1463.             break;
  1464.     }
  1465.  
  1466.     ScrollLineEraseLine(Value);
  1467.  
  1468.     DrawCursor();
  1469.  
  1470.     RasterEraseLine(Value);
  1471.  
  1472.     BackupRender();
  1473.  
  1474.     return(NULL);
  1475. }
  1476.  
  1477.     /* EraseScreen(UBYTE *Buffer):
  1478.      *
  1479.      *    Erase parts of the screen.
  1480.      */
  1481.  
  1482. UBYTE * __regargs
  1483. EraseScreen(UBYTE *Buffer)
  1484. {
  1485.     WORD Value;
  1486.     BYTE Shift;
  1487.  
  1488.     if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  1489.         Shift = 4;
  1490.     else
  1491.     {
  1492.         if(Config . FontScale == SCALE_HALF)
  1493.             Shift = 2;
  1494.         else
  1495.             Shift = 3;
  1496.     }
  1497.  
  1498.     ClearCursor();
  1499.  
  1500.     ReadValue(Buffer,&Value);
  1501.  
  1502.     BackupRender();
  1503.  
  1504.     SetAPen(RPort,0);
  1505.  
  1506.     switch(Value)
  1507.     {
  1508.         case 1:    if(CursorY)
  1509.                 ScrollLineRectFill(RPort,0,0,LastPixel,(CursorY * 8) - 1);
  1510.  
  1511.             ScrollLineRectFill(RPort,0,CursorY * 8,((CursorX + 1) << Shift) - 1,(CursorY + 1) * 8 - 1);
  1512.  
  1513.             break;
  1514.  
  1515.         case 2:    ScrollLineRectFill(RPort,0,0,LastPixel,(LastLine + 1) * 8 - 1);
  1516.             break;
  1517.  
  1518.         default:ScrollLineRectFill(RPort,CursorX << Shift,CursorY * 8,LastPixel,(CursorY + 1) * 8 - 1);
  1519.  
  1520.             if(CursorY != LastLine)
  1521.                 ScrollLineRectFill(RPort,0,(CursorY + 1) * 8,LastPixel,(LastLine + 1) * 8 - 1);
  1522.  
  1523.             break;
  1524.     }
  1525.  
  1526.     ScrollLineEraseScreen(Value);
  1527.  
  1528.     RasterEraseScreen(Value);
  1529.  
  1530.     DrawCursor();
  1531.  
  1532.     BackupRender();
  1533.  
  1534.     return(NULL);
  1535. }
  1536.  
  1537.     /* EraseCharacters(UBYTE *Buffer):
  1538.      *
  1539.      *    Erase a number of characters.
  1540.      */
  1541.  
  1542. UBYTE * __regargs
  1543. EraseCharacters(UBYTE *Buffer)
  1544. {
  1545.     WORD Value;
  1546.  
  1547.     ReadValue(Buffer,&Value);
  1548.  
  1549.     BackupRender();
  1550.  
  1551.     SetBPen(RPort,0);
  1552.  
  1553.     if(Value == -1)
  1554.         Value = 1;
  1555.  
  1556.     if(Value > 0)
  1557.     {
  1558.         BYTE Shift;
  1559.  
  1560.         if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  1561.             Shift = 4;
  1562.         else
  1563.         {
  1564.             if(Config . FontScale == SCALE_HALF)
  1565.                 Shift = 2;
  1566.             else
  1567.                 Shift = 3;
  1568.         }
  1569.  
  1570.         RasterEraseCharacters(Value);
  1571.  
  1572.         ScrollLineEraseCharacters(Value);
  1573.  
  1574.         ClearCursor();
  1575.  
  1576.         ScrollLineRaster(RPort,Value << Shift,0,CursorX << Shift,CursorY * 8,LastPixel,(CursorY + 1) * 8 - 1);
  1577.  
  1578.         DrawCursor();
  1579.     }
  1580.  
  1581.     BackupRender();
  1582.  
  1583.     return(NULL);
  1584. }
  1585.  
  1586.     /* InsertLine(UBYTE *Buffer):
  1587.      *
  1588.      *    Insert a number of lines and scroll the rest of the
  1589.      *    display down.
  1590.      */
  1591.  
  1592. UBYTE * __regargs
  1593. InsertLine(UBYTE *Buffer)
  1594. {
  1595.     WORD Value;
  1596.  
  1597.     ReadValue(Buffer,&Value);
  1598.  
  1599.     BackupRender();
  1600.  
  1601.     SetAPen(RPort,0);
  1602.  
  1603.     if(Value == -1)
  1604.         Value = 1;
  1605.  
  1606.     if(Value > 0)
  1607.     {
  1608.         WORD RegionBottom,RegionTop,TheTop = CursorY;
  1609.  
  1610.         if(RegionSet)
  1611.         {
  1612.             RegionTop    = Top;
  1613.             RegionBottom    = Bottom + 1;
  1614.         }
  1615.         else
  1616.         {
  1617.             RegionTop    = 0;
  1618.             RegionBottom    = LastLine + 1;
  1619.         }
  1620.  
  1621.         if(TheTop < RegionTop)
  1622.             TheTop = RegionTop;
  1623.  
  1624.         RasterInsertLine(Value,TheTop);
  1625.  
  1626.         ClearCursor();
  1627.  
  1628.         ScrollLineRaster(RPort,0,-(Value * 8),0,TheTop * 8,LastPixel,RegionBottom * 8 - 1);
  1629.  
  1630.         DrawCursor();
  1631.     }
  1632.  
  1633.     BackupRender();
  1634.  
  1635.     return(NULL);
  1636. }
  1637.  
  1638.     /* ClearLine(UBYTE *Buffer):
  1639.      *
  1640.      *    Clear a number of lines and scroll up the ones below it.
  1641.      */
  1642.  
  1643. UBYTE * __regargs
  1644. ClearLine(UBYTE *Buffer)
  1645. {
  1646.     WORD Value;
  1647.  
  1648.     ReadValue(Buffer,&Value);
  1649.  
  1650.     BackupRender();
  1651.  
  1652.     SetAPen(RPort,0);
  1653.  
  1654.     if(Value == -1)
  1655.         Value = 1;
  1656.  
  1657.     if(Value > 0)
  1658.     {
  1659.         WORD RegionBottom,RegionTop,TheTop = CursorY;
  1660.  
  1661.         if(RegionSet)
  1662.         {
  1663.             RegionTop    = Top;
  1664.             RegionBottom    = Bottom + 1;
  1665.         }
  1666.         else
  1667.         {
  1668.             RegionTop    = 0;
  1669.             RegionBottom    = LastLine + 1;
  1670.         }
  1671.  
  1672.         if(TheTop < RegionTop)
  1673.             TheTop = RegionTop;
  1674.  
  1675.         RasterClearLine(Value,TheTop);
  1676.  
  1677.         ClearCursor();
  1678.  
  1679.         ScrollLineRaster(RPort,0,Value * 8,0,TheTop * 8,LastPixel,RegionBottom * 8 - 1);
  1680.  
  1681.         DrawCursor();
  1682.     }
  1683.  
  1684.     BackupRender();
  1685.  
  1686.     return(NULL);
  1687. }
  1688.  
  1689.     /* SetTabs(UBYTE *Buffer):
  1690.      *
  1691.      *    Set the current tab stops.
  1692.      */
  1693.  
  1694. UBYTE * __regargs
  1695. SetTabs(UBYTE *Buffer)
  1696. {
  1697.     WORD Value;
  1698.  
  1699.     ReadValue(Buffer,&Value);
  1700.  
  1701.     if(Value == -1)
  1702.         Value = 0;
  1703.  
  1704.     switch(Value)
  1705.     {
  1706.         case 0:    if(CursorX < 1024)
  1707.                 TabStops[CursorX] = FALSE;
  1708.  
  1709.             break;
  1710.  
  1711.         case 3:    memset(&TabStops[0],FALSE,1024);
  1712.  
  1713.             break;
  1714.  
  1715.         default:break;
  1716.     }
  1717.  
  1718.     return(NULL);
  1719. }
  1720.  
  1721.     /* SetAbsolutePosition(UBYTE *Buffer):
  1722.      *
  1723.      *    Move the cursor to a given location on the display,
  1724.      *    this routine ignores the current scroll region
  1725.      *    settings.
  1726.      */
  1727.  
  1728. UBYTE * __regargs
  1729. SetAbsolutePosition(UBYTE *Buffer)
  1730. {
  1731.     WORD Value;
  1732.  
  1733.     Buffer = ReadValue(Buffer,&Value);
  1734.  
  1735.     ClearCursor();
  1736.  
  1737.     if(UseRegion && RegionSet)
  1738.         CursorY = Top;
  1739.     else
  1740.         CursorY = 0;
  1741.  
  1742.     CursorX = 0;
  1743.  
  1744.     if(Value != -1)
  1745.     {
  1746.             /* Our raster origin is 0/0 instead of 1/1. */
  1747.  
  1748.         if(Value)
  1749.             Value--;
  1750.  
  1751.         if(UseRegion && RegionSet)
  1752.             CursorY = Top + Value;
  1753.         else
  1754.             CursorY = Value;
  1755.  
  1756.         if(Buffer)
  1757.         {
  1758.             ReadValue(Buffer,&Value);
  1759.  
  1760.             if(Value > 0)
  1761.                 CursorX = Value - 1;
  1762.             else
  1763.                 CursorX = 0;
  1764.         }
  1765.  
  1766.             /* Truncate illegal positions. */
  1767.  
  1768.         if(CursorX > LastColumn)
  1769.             CursorX = LastColumn;
  1770.  
  1771.         if(CursorY > LastLine)
  1772.             CursorY = LastLine;
  1773.     }
  1774.  
  1775.     SetCursor();
  1776.  
  1777.     return(NULL);
  1778. }
  1779.  
  1780.     /* SetAttributes(UBYTE *Buffer):
  1781.      *
  1782.      *    Set the current display rendering attributes.
  1783.      */
  1784.  
  1785. UBYTE * __regargs
  1786. SetAttributes(UBYTE *Buffer)
  1787. {
  1788.     LONG TextFlags = FS_NORMAL;
  1789.     WORD Value;
  1790.  
  1791.     ClearCursor();
  1792.  
  1793.     do
  1794.     {
  1795.         Buffer = ReadValue(Buffer,&Value);
  1796.  
  1797.         if(Value == -1)
  1798.             Value = 0;
  1799.  
  1800.         switch(Value)
  1801.         {
  1802.             case 0:    switch(Config . ColourMode)
  1803.                 {
  1804.                     case COLOUR_AMIGA:
  1805.                     case COLOUR_MONO:    FgPen = 1;
  1806.                                 break;
  1807.  
  1808.                     case COLOUR_EIGHT:    FgPen = 7;
  1809.                                 break;
  1810.  
  1811.                     case COLOUR_SIXTEEN:    FgPen = 15;
  1812.                                 break;
  1813.                 }
  1814.  
  1815.                 BgPen = 0;
  1816.  
  1817.                 if(RPort -> FgPen != FgPen)
  1818.                     SetAPen(RPort,FgPen);
  1819.  
  1820.                 if(RPort -> BgPen != BgPen)
  1821.                     SetBPen(RPort,BgPen);
  1822.  
  1823.                 Attributes = 0;
  1824.  
  1825.                 break;
  1826.  
  1827.             case 1:    Attributes |= ATTR_HIGHLIGHT;
  1828.  
  1829.                 break;
  1830.  
  1831.             case 4:    Attributes |= ATTR_UNDERLINE;
  1832.  
  1833.                 break;
  1834.  
  1835.             case 5:    Attributes |= ATTR_BLINK;
  1836.  
  1837.                 break;
  1838.  
  1839.             case 7:    if(!(Attributes & ATTR_INVERSE))
  1840.                 {
  1841.                     BYTE Help;
  1842.  
  1843.                     Help    = FgPen;
  1844.                     FgPen    = BgPen;
  1845.                     BgPen    = Help;
  1846.                 }
  1847.  
  1848.                 Attributes |= ATTR_INVERSE;
  1849.  
  1850.                 break;
  1851.  
  1852.             default:if(Value >= 30)
  1853.                 {
  1854.                     if(Value <= 37)
  1855.                     {
  1856.                         if(Attributes & ATTR_INVERSE)
  1857.                             BgPen = Value - 30;
  1858.                         else
  1859.                             FgPen = Value - 30;
  1860.                     }
  1861.                     else
  1862.                     {
  1863.                         if(Value >= 40 && Value <= 47)
  1864.                         {
  1865.                             if(Attributes & ATTR_INVERSE)
  1866.                                 FgPen = Value - 40;
  1867.                             else
  1868.                                 BgPen = Value - 40;
  1869.                         }
  1870.                     }
  1871.                 }
  1872.  
  1873.                 break;
  1874.         }
  1875.     }
  1876.     while(Buffer);
  1877.  
  1878.     if(Attributes & ATTR_UNDERLINE)
  1879.         TextFlags |= FSF_UNDERLINED;
  1880.  
  1881.     if(Attributes & ATTR_HIGHLIGHT)
  1882.     {
  1883.         if(Config . ColourMode == COLOUR_SIXTEEN)
  1884.         {
  1885.             if(Attributes & ATTR_INVERSE)
  1886.                 BgPen |= 8;
  1887.             else
  1888.                 FgPen |= 8;
  1889.         }
  1890.         else
  1891.             TextFlags |= FSF_BOLD;
  1892.     }
  1893.  
  1894.     if(Attributes & ATTR_BLINK)
  1895.     {
  1896.         if(Config . Emulation == EMULATION_ANSIVT100)
  1897.         {
  1898.             switch(Config . ColourMode)
  1899.             {
  1900.                 case COLOUR_AMIGA:    if(Attributes & ATTR_INVERSE)
  1901.                                 BgPen = 3;
  1902.                             else
  1903.                                 FgPen = 3;
  1904.                             break;
  1905.  
  1906.                 case COLOUR_EIGHT:    if(Attributes & ATTR_INVERSE)
  1907.                                 BgPen |= 8;
  1908.                             else
  1909.                                 FgPen |= 8;
  1910.                             break;
  1911.  
  1912.                 case COLOUR_SIXTEEN:    break;
  1913.  
  1914.                 case COLOUR_MONO:    if(Attributes & ATTR_INVERSE)
  1915.                                 BgPen = 1;
  1916.                             else
  1917.                                 FgPen = 1;
  1918.  
  1919.                             break;
  1920.             }
  1921.         }
  1922.     }
  1923.  
  1924.     if(TextFlags != StyleType)
  1925.     {
  1926.         SetSoftStyle(RPort,TextFlags,0xFF);
  1927.  
  1928.         StyleType = TextFlags;
  1929.     }
  1930.  
  1931.     if(Config . ColourMode == COLOUR_MONO)
  1932.     {
  1933.         if((FgPen & 1) == (BgPen & 1))
  1934.         {
  1935.             if(ColourValue(FgPen) < ColourValue(BgPen))
  1936.             {
  1937.                 if(Attributes & ATTR_INVERSE)
  1938.                 {
  1939.                     FgPen = 1;
  1940.                     BgPen = 0;
  1941.                 }
  1942.                 else
  1943.                 {
  1944.                     FgPen = 0;
  1945.                     BgPen = 1;
  1946.                 }
  1947.             }
  1948.             else
  1949.             {
  1950.                 if(Attributes & ATTR_INVERSE)
  1951.                 {
  1952.                     FgPen = 0;
  1953.                     BgPen = 1;
  1954.                 }
  1955.                 else
  1956.                 {
  1957.                     FgPen = 1;
  1958.                     BgPen = 0;
  1959.                 }
  1960.             }
  1961.         }
  1962.     }
  1963.  
  1964.     if(FgPen != RPort -> FgPen)
  1965.         SetAPen(RPort,FgPen);
  1966.  
  1967.     if(BgPen != RPort -> BgPen)
  1968.         SetBPen(RPort,BgPen);
  1969.  
  1970.     SetCursor();
  1971.  
  1972.     return(NULL);
  1973. }
  1974.  
  1975.     /* SetRegion(UBYTE *Buffer):
  1976.      *
  1977.      *    Set the current scroll region top and bottom.
  1978.      */
  1979.  
  1980. UBYTE * __regargs
  1981. SetRegion(UBYTE *Buffer)
  1982. {
  1983.     WORD NewTop,Value,NewBottom = LastLine;
  1984.  
  1985.     Buffer = ReadValue(Buffer,&Value);
  1986.  
  1987.     if(Value > 0)
  1988.     {
  1989.         NewTop = Value;
  1990.  
  1991.         if(Value > 0)
  1992.             NewTop = Value - 1;
  1993.  
  1994.         if(Buffer)
  1995.         {
  1996.             ReadValue(Buffer,&Value);
  1997.  
  1998.             if(Value > 0)
  1999.                 NewBottom = Value - 1;
  2000.         }
  2001.  
  2002.         if(NewBottom > LastLine)
  2003.             NewBottom = LastLine;
  2004.  
  2005.         if(NewTop > LastLine)
  2006.             NewTop = LastLine;
  2007.     }
  2008.     else
  2009.     {
  2010.         NewTop        = 0;
  2011.         NewBottom    = LastLine;
  2012.     }
  2013.  
  2014.     if(NewTop < NewBottom)
  2015.     {
  2016.         if(NewTop != 0 || NewBottom != LastLine)
  2017.         {
  2018.             Top    = NewTop;
  2019.             Bottom    = NewBottom;
  2020.  
  2021.             RegionSet = TRUE;
  2022.         }
  2023.         else
  2024.             UseRegion = RegionSet = FALSE;
  2025.  
  2026.         ResetCursor();
  2027.     }
  2028.     else
  2029.         RegionSet = FALSE;
  2030.  
  2031.     return(NULL);
  2032. }
  2033.  
  2034.     /* ResetCursor():
  2035.      *
  2036.      *    Reset cursor to top of screen.
  2037.      */
  2038.  
  2039. VOID
  2040. ResetCursor()
  2041. {
  2042.     ClearCursor();
  2043.  
  2044.     CursorX    = 0;
  2045.  
  2046.     if(UseRegion && RegionSet)
  2047.         CursorY = Top;
  2048.     else
  2049.         CursorY    = 0;
  2050.  
  2051.     SetCursor();
  2052. }
  2053.